iT邦幫忙

2025 iThome 鐵人賽

DAY 29
0
佛心分享-SideProject30

30天的旅程!從學習C#到開發小專案系列 第 29

DAY 29 - AuthService: 使用者登入狀態管理中心

  • 分享至 

  • xImage
  •  

哈囉大家好!不知不覺來到鐵人賽的第29天了,時間過得好快啊~
今天想要分享前端管理登入狀態的優化-建立AuthService來作為使用者的狀態管理中心。

目前在驗證使用者登入狀態時,是從localStorage讀取。考量到日後應用程式的擴展性和維護性,想要把使用者的狀態存取在全域可觀察的Observable!

建立AuthService來管理使用者狀態

首先,在專案中建立一個新的AuthService來作為狀態管理中心,具體流程如下:

  1. 建立loggedInSubject來追蹤使用者的登入狀態,並且在AuthService中做token統一管理。
  2. 建立observable isLoggedIn$,提供外部component做訂閱使用。
  3. 新增function hasToken,檢查localStorage中是否有儲存token。
  4. 新增saveToken function來統一處理token的儲存,並將更新的登入狀態廣播給所有訂閱者。
  5. 新增getToken function來統一處理token的讀取。
  6. 新增logout function,當使用者登出時,移除localStorage中儲存的token,並將更新的使用者狀態廣播給訂閱者。
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';

const TOKEN_KEY = 'go_dutch_session_token';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  // BehaviorSubject儲存當前登入狀態
  private loggedInSubject = new BehaviorSubject<boolean>(this.hasToken());

  // 提供外部訂閱的Observable
  isLoggedIn$: Observable<boolean> = this.loggedInSubject.asObservable();
  constructor(private router: Router) {}

  // 檢查localStorage中是否有token
  private hasToken(): boolean {
    return !!localStorage.getItem(TOKEN_KEY);
  }

  // 使用者登入成功,儲存session token
  public saveToken(token: string): void {
    localStorage.setItem(TOKEN_KEY, token);
    // 更新狀態為已登入,廣播給所有subscriber
    this.loggedInSubject.next(true);
  }

  // 提供interceptor和service讀取token使用
  public getToken(): string | null {
    return localStorage.getItem(TOKEN_KEY);
  }

  // 處理使用者登出
  public logout(): void {
    localStorage.removeItem(TOKEN_KEY); // 移除token

    this.loggedInSubject.next(false); // 更新狀態為"未登入"
    
    this.router.navigate(['/login']); // 導航至登入頁面
  }
}

明天就是鐵人賽的最後一天了,預計會分享一下這次的參賽心得,以及把這三十天的分享做個小整理和總結~


上一篇
DAY 28 - Token過期時的錯誤處理
系列文
30天的旅程!從學習C#到開發小專案29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言